package com.example.screenprojection.Socket;

import android.graphics.Bitmap;
import android.util.Log;

import com.example.screenprojection.Utils.MyUtils;

import org.json.JSONObject;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;

public class TouchServerRunnable implements Runnable{

    private static final String TAG = "TouchServerRunnable";

    private ServerSocket serverSocket;
    private Socket socket;
    private int port;


    public void setPort(int port) {
        this.port = port;
    }

    @Override
    public void run() {
        ServerRun();
    }

    public void close() {
        ServerClose();
    }

    private boolean ServerCreate() {
        try {
            serverSocket = new ServerSocket(port, 1);
        } catch (Exception e) {
            e.printStackTrace();
            if (listener != null) {
                listener.onServerClose();
            }
            return false;
        }
        return true;
    }

    private boolean ServerListen() {
        try {
            socket = serverSocket.accept();
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        if (listener != null) {
            listener.onServerConnect();
        }
        return true;
    }

    private boolean ServerIsConnect() {
        return socket != null && !socket.isClosed() && socket.isConnected();
    }

    private void ServerClose() {
        try {
            if (socket != null) {
                socket.close();
                serverSocket.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (listener != null) {
            listener.onServerClose();
        }
    }

    private void ServerSleep(long millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private final static byte[] PACKAGE_HEAD = {(byte)0xFF, (byte)0xCF, (byte)0xFA, (byte)0xBF, (byte)0xF6, (byte)0xAF, (byte)0xFE, (byte)0xFF};

    private void ServerReceiveTouchPosition() {
        try {
            InputStream inputStream = socket.getInputStream();
            boolean isHead = true;
            for (byte b : PACKAGE_HEAD) {
                byte head = (byte) inputStream.read();
                if (head != b) {
                    isHead = false;
                    break;
                }
            }
            if (isHead) {
                DataInputStream dataInputStream = new DataInputStream(inputStream);
                int len = dataInputStream.readInt();
                byte[] bytes = new byte[len];
                dataInputStream.readFully(bytes, 0, len);
                final String msg = MyUtils.BytestoString(bytes);
                JSONObject jsonObject = new JSONObject(msg);
                int staX = jsonObject.getInt("staX");
                int staY = jsonObject.getInt("staY");
                int endX = jsonObject.getInt("endX");
                int endY = jsonObject.getInt("endY");
                int keyC = jsonObject.getInt("keyC");
                if (listener != null) {
                    listener.onServerReceiveTouchPosition(staX, staY, endX, endY, keyC);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void ServerRun() {
        if (!ServerCreate()) {
            return;
        }
        while (true) {
            if (!ServerListen()) {
                break;
            }
            while (ServerIsConnect()) {
                ServerReceiveTouchPosition();
                ServerSleep(10);
            }
        }
    }

    private ServerListener listener;

    public void setListener(ServerListener listener) {
        this.listener = listener;
    }

    public interface ServerListener {
        void onServerConnect();
        void onServerClose();
        void onServerReceiveTouchPosition(int staX, int staY, int endX, int endY, int keyC);
    }
}
